package com.wanshu.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wanshu.common.annotation.SysLogger;
import com.wanshu.common.constant.SystemConstant;
import com.wanshu.sys.entity.SysRole;
import com.wanshu.sys.mapper.SysRoleMapper;
import com.wanshu.sys.model.SysUserQueryDto;
import com.wanshu.common.util.PageUtils;
import com.wanshu.sys.entity.SysUser;
import com.wanshu.sys.mapper.SysUserMapper;
import com.wanshu.sys.model.res.roleMenuTree.UserRoleMenuRes;
import com.wanshu.sys.service.ISysRoleService;
import com.wanshu.sys.service.ISysUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.catalina.realm.SecretKeyCredentialHandler;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 系统用户 服务实现类
 * </p>
 *
 * @author 波哥
 * @since 2023-05-09
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {

    @Resource
    private ISysRoleService sysRoleService;

    @Override
    public List<SysUser> queryByUserName(String username) {
        //这里只是演示，为了避免魔法值硬编码，可以使用 LambdaQueryWrapper
//        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
//        wrapper.eq(StringUtils.isNotBlank(username),"username",username);
//        List<SysUser> userList = this.getBaseMapper().selectList(wrapper);
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper();
        wrapper.eq(StringUtils.isNotBlank(username), SysUser::getUsername, username);
        wrapper.eq(SysUser::getStatus, SystemConstant.USER_STATUS_NORMAL); //只查启用的
        List<SysUser> userList = this.getBaseMapper().selectList(wrapper);
        return userList;
    }

    @Override
    public PageUtils<SysUser> queryPage(SysUserQueryDto sysUserQueryDto) {
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper();
        wrapper.like(StringUtils.isNotBlank(sysUserQueryDto.getUsername()), SysUser::getUsername, sysUserQueryDto.getUsername());
        Page<SysUser> page = this.page(sysUserQueryDto.page(), wrapper);
        return new PageUtils<>(page);
    }

    @Override
    public Boolean existUserName(SysUser sysUser) {
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(StringUtils.isNotBlank(sysUser.getUsername()), SysUser::getUsername, sysUser.getUsername())
                .ne(sysUser.getUserId() != null, SysUser::getUserId, sysUser.getUserId());
        int count = this.count(queryWrapper);
        return count > 0;
    }

    @SysLogger("新增或修改系统角色")
    @Transactional
    @Override
    public void saveUser(SysUser sysUser) {
        /* ### 1、新增/更新用户数据 ## */
        /* 密码加密 */
        String password = sysUser.getPassword();
        if (password != null) {
            sysUser.setPassword(new BCryptPasswordEncoder().encode(password));
        }
        /* 新建或更新 */
        if (sysUser.getUserId() != null) {
            /** 更新 */
            this.update(sysUser);
        } else {
            /** 新建*/
            //设置创建时间
            sysUser.setCreateTime(LocalDateTime.now());
            //设置创建人。 从安全上下文中获取认证信息
            sysUser.setCreateUserId(getCurrentUserId());
            this.save(sysUser);
        }
        /* ### 2、插入用户角色关联数据 ## */
        /*2。1 清除历史数据*/
        //更新时才需要清除
        if (sysUser.getUserId() != null) {
            this.baseMapper.deleteRolesByUserId(sysUser.getUserId());
        }
        /*2。2 插入新数据*/
        if (sysUser.getRoleIds().size()>0){
            for (Long roleId : sysUser.getRoleIds()) {
                this.baseMapper.insertUserRoles(sysUser.getUserId(),roleId);
            }
        }
    }

    /**
     * 查询用户
     *
     * @param sysUser 系统用户
     * @return {@link List }<{@link SysUser }>
     * @author 张颖辉（zyh）
     * @date 2023/06/30
     * @version 1.0.0
     */
//    public List<SysUser> queryUser(SysUser sysUser) {
//        LambdaQueryWrapper wrapper = new LambdaQueryWrapper<SysUser>()
//                .eq(sysUser.getUserId() != null, SysUser::getUserId, sysUser.getUserId())
//                .eq(StringUtils.isNotBlank(sysUser.getUsername()), SysUser::getUsername, sysUser.getUsername())
//                .eq(StringUtils.isNotBlank(sysUser.getEmail()), SysUser::getEmail, sysUser.getEmail())
//                .eq(StringUtils.isNotBlank(sysUser.getMobile()), SysUser::getMobile, sysUser.getMobile());
//        return baseMapper.selectList(wrapper);
//    }

    /**
     * 通过id查询用户
     *
     * @param userId 用户id
     * @return {@link SysUser }
     * @author 张颖辉（zyh）
     * @date 2023/06/30
     * @version 1.0.0
     */
    @Override
    public UserRoleMenuRes queryUserById(Long userId) {
        UserRoleMenuRes res = new UserRoleMenuRes();
        /* 1 查询用户信息 */
        //查询用户信息
        SysUser sysUser = baseMapper.selectById(userId);
        //避免暴露密码，设置密码为空
        sysUser.setPassword(null);
        //设置用户对应的角色id列表
        List<Long> roleIds = baseMapper.selectRoleIdsByUserId(userId);
        sysUser.setRoleIds(roleIds);

        res.setSysUser(sysUser);

        /* 2 查询全量角色信息 */
        List<SysRole> roles = sysRoleService.list();
        res.setSysRoles(roles);
        return res;
    }

    /**
     * 获得当前登录用户id
     *
     * @return {@link Long }
     * @author 张颖辉（zyh）
     * @date 2023/06/30
     * @version 1.0.0
     */
    private Long getCurrentUserId() {
        UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
        String userName = (String) authentication.getPrincipal();
        List<SysUser> userList = this.baseMapper.selectList(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUsername, userName));
        if (userList != null && !userList.isEmpty()) {
            SysUser sysUser = userList.get(0);
            return sysUser.getUserId();
        }
        return null;
    }

    /**
     * 更新
     *
     * @param sysUser 系统用户
     * @author 张颖辉（zyh）
     * @date 2023/06/30
     * @version 1.0.0
     */
    private void update(SysUser sysUser) {
        //这里只更新非空属性
        this.baseMapper.updateById(sysUser);
    }
}
